unit HSV;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;

type
  TForm1 = class(TForm)
    Image1: TImage;
    Button1: TButton;
    Timer1: TTimer;
    Timer2: TTimer;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure Timer2Timer(Sender: TObject);
  private
    { Private declarations }
  public
    procedure Draw;
    procedure Pull;
  end;
const
yo = 50;
xo = 0;
R = 10;
var
  Form1: TForm1;
  w, n : integer;
  arr : array of integer;
  p, k, i : integer;
  x, y : real;
  state, q, num, m : integer;
implementation

{$R *.dfm}


procedure TForm1.Draw;
var
  x1, y1 : integer;
begin
  x := xo + (w)/(2*p) + ((i-p+1)*w)/p;
  y := yo*(k+1);
  x1 :=round(x);
  y1:=round(y);
  Form1.Image1.Canvas.Ellipse(x1-R,y1-R,x1+R,y1+R);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  w := Image1.Width;
  n := 30;
  setlength(arr, n);
  for i:=0 to n-1 do
    arr[i] := random(50);
  k := 0;
  p := 1;
  for i:=0 to n-1 do
  begin
    Draw;
    if(i+2=2*p) then
    begin
      k := k+1;
      p := 2*p;
    end;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Timer1.Enabled := True;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var temp : integer;
begin
  if state=0 then
  begin
    q := n-1;
    state := 1;
    Pull;
  end;
  if state=1 then
  begin
    num := q;
    Timer2.Enabled := True;
    Timer1.Enabled := False;
    q := q-1;
    if q=-1 then
      state := 2;
    Pull
  end;
  if state=2 then
  begin
    m := n;
    q := 0;
    state := 3;
    Pull;
  end;
  if state=3 then
  begin
    temp := arr[0];
    arr[0] := arr[n-1];
    arr[n-1] := temp;
    n := n-1;
    num := 0;
    Timer2.Enabled := True;
    Timer1.Enabled := False;
    q := q+1;
    if q=m then state := 4;
    Pull;
  end;
  if state = 4 then
  begin
    n := m;
    Pull;
    Timer1.Enabled := False;
  end;
end;

procedure TForm1.Timer2Timer(Sender: TObject);
var a, b, temp: integer;
begin
  a := 20000;
  b := 20000;
  if (2*num+1)< n then
    a := arr[2*num+1];
  if (2*num+2)< n then
    a := arr[2*num+2];
  if (a<=b) and (a<arr[num]) then
  begin
    temp := arr[num];
    arr[num] := arr[2*num+1];
    arr[2*num+1] := temp;
    num := 2*num+1;
  end else if (b < a) and (b<arr[num]) then
  begin
    temp := arr[num];
    arr[num] := arr[2*num+1];
    arr[2*num+1] := temp;
    num := 2*num+1;
  end else
  begin
    Timer1.Enabled := True;
    Timer2.Enabled := False;
  end;
end;

procedure TForm1.Pull;
var x1, y1 : integer;
begin
  k := 0;
  p := 1;
  for i:=0 to n-1 do
  begin
    x := xo + (w)/(2*p) + ((i-p+1)*w)/p;
    y := yo*(k+1);
    x1 :=round(x);
    y1:=round(y);
    Image1.Canvas.TextOut(x1, y1, inttostr(arr[i]));
    if(i+2=2*p) then
    begin
      k := k+1;
      p := 2*p;
    end;
  end;
end;

end.
